/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package src.network;

import src.engine.PICAIUDice;
import src.engine.PICAIUVector;
import src.objects.PICAIUGameUnit;

/**
 *
 * @author Owner
 */
public class PICAIURecruittedUnit {

  protected long id = -1;
  protected int type = 0;
  protected int worth = 0;
  protected int health = 0;
  protected int energy = 0;
  protected int maxEnergy = 0;
  protected int vision = 0;
  protected int accuracy = 0;
  protected int curiousity = 0;
  protected int bravery = 0;
  private PICAIUVector position = new PICAIUVector();
  private PICAIUServerPersona owner;
  private PICAIUAIMastermind mind;
  protected PICAIUVector target = new PICAIUVector(1400, 1000);
  //target's movement
  protected PICAIUVector velocity = new PICAIUVector();
  public static float RUNSPEED = .275f;
  public static float MOVESPEED = .1f;
  protected float rotateSpeed = .3f;
  protected float moveSpeed = MOVESPEED;
  //
  public static final int NORMAL = 0;
  public static final int GOPRONE = 1;
  public static final int PRONE = 2;
  public static final int UNPRONE = 3;
  public static final int BLOCKED = 4;
  public static final int SHOOT = 5;
  public static final int SHOOTPRONE = 6;
  public static final int RUN = 7;
  public static final int MOVE = 8;
  public static final int REST = 9;
  public static final int DEAD = 10;
  private int restNum;
  int status = NORMAL;
  int rechargeCount = 0;
  int rechargeRate = 2070;
  float moveCounter;
  PICAIURecruittedUnit toAttack;

  PICAIURecruittedUnit(long id, int type, int worth, int health, int energy, int vision, int accuracy, int curiousity, int bravery, PICAIUServerPersona ownedBy) {
    this.id = id;
    this.type = type;
    this.worth = worth;
    this.health = health;
    this.energy = this.maxEnergy = energy;
    this.vision = vision;
    this.accuracy = accuracy;
    this.curiousity = curiousity;
    this.bravery = bravery;
    owner = ownedBy;
  }

  public PICAIURecruittedUnit(long id, int type, int worth, int health, int energy, int vision, int accuracy, PICAIUServerPersona ownedBy) {
    this.id = id;
    this.type = type;
    this.worth = worth;
    this.health = health;
    this.energy = this.maxEnergy = energy;
    this.vision = vision;
    this.accuracy = accuracy;
    owner = ownedBy;
  }

  public String getFormattedInfo1() {
    return "Price = " + worth + "   Sells for = " + (worth * PICAIUServer.UNITRETURNRATE);
  }

  public String getFormattedInfo2() {
    return "Health: " + health + "   Energy: " + energy;
  }

  public String getFormattedInfo3() {
    return "Vision: " + vision + "   Accur:" + accuracy;
  }

  public String getID() {
    return "" + id;
  }

  public int getType() {
    return type;
  }

  String getBasicDataString() {
    return id + "#" + type + "#" + vision;
  }

  String getFullDataString() {
    return id + "#" + type + "#" + health + "#" + energy + "#" + vision + "#" + accuracy + "#" + curiousity + "#" + bravery;
  }

  String getNetworkString() {
    return id + "#" + status + "#" + ((int) position.getX()) + "#" + ((int) position.getY() + "#" + ((int) target.getX()) + "#" + ((int) target.getY()));
  }

  void setX(float x) {
    position.setX(x);
  }

  void setY(float y) {
    position.setY(y);
  }

  public double getX() {
    return position.getX();
  }

  public double getY() {
    return position.getY();
  }

  boolean isRedTeam() {
    return owner.isRedTeam();
  }

  void initAI(PICAIUGame g) {
    mind = new PICAIUAIMastermind(this, g);
  }

  protected void moveTowardsTarget(long deltaT) {

    if (deltaT < 1) {
      deltaT = 1;
    }
    if (status == REST) {
      return;
    }

    if (target.getX() < position.getX() - moveSpeed * deltaT) {
      velocity.setX(-moveSpeed * deltaT);
    } else if (target.getX() > position.getX() + moveSpeed * deltaT) {
      velocity.setX(moveSpeed * deltaT);
    } else {
      velocity.setX(0);
      status = NORMAL;
    }


    if (target.getY() < position.getY() - moveSpeed * deltaT) {
      velocity.setY(-moveSpeed * deltaT);
    } else if (target.getY() > position.getY() + moveSpeed * deltaT) {
      velocity.setY(moveSpeed * deltaT);
    } else {
      velocity.setY(0);
      status = NORMAL;
    }


    if (energy <= 0) {
      //System.out.println("NOT ENOUGH ENERGY TO MOVE");
      energy = 0;
      velocity.setX(0);
      velocity.setY(0);
      status = REST;
      restNum=100;
    }

    if (status == RUN || status == MOVE) {

      moveCounter += Math.abs(velocity.getX());
      moveCounter += Math.abs(velocity.getY());
      while (moveCounter > 100) {
        //System.out.println("SUBTRACTING ONE ENERGY DURING MOVE");
        moveCounter -= 100;
        energy--;
      }


      position.addToX(velocity.getX());
      position.addToY(velocity.getY());

      if (position.getX() < 0) {
        position.setX(0);
        velocity.setX(0);
      }
      if (position.getY() < 0) {
        position.setY(0);
        velocity.setY(0);
      }

      if (position.getX() > owner.getGame().mapWidth - 50) {
        position.setX(owner.getGame().mapWidth - 50);
        velocity.setX(0);
      }
      if (position.getY() > owner.getGame().mapHeight - 50) {
        position.setY(owner.getGame().mapHeight - 50);
        velocity.setY(0);
      }
    }
  }

  void update(long deltaT) {
    //if (isRedTeam()) {
      //System.out.println("Status:"+status);
      //System.out.println("Energy:"+energy);
    //}
    if (status == DEAD) {
      return;
    }
    recharge(deltaT);
    restUpdate(deltaT);
    moveTowardsTarget(deltaT);
    shootTarget(toAttack);
  }

  private void restUpdate(long deltaT) {
    if (status == REST) {
      if (restNum > 0) {
        restNum -= deltaT;
      }

      if (restNum <= 0) {
        restNum = 0;
        //System.out.println("STATUS SET TO NORMAL IN REST UPDATE");
        status = NORMAL;
      }
    }
  }

  void updateAI() {
    if (status == DEAD) {
      return;
    }
    mind.update();
  }

  void rest(int restNum) {
    if (status != REST) {
      status = REST;
      this.restNum = restNum;
    }
  }

  private void recharge(long deltaT) {
    if (energy < 0) {
      energy = 0;
    }
    rechargeCount += deltaT;
    if (rechargeCount >= rechargeRate) {
      rechargeCount -= rechargeRate;
      if (status == REST) {
        energy += 3;
      } else {
        energy += 1;
      }
    }
    if (energy >= maxEnergy) {
      energy = maxEnergy;
      restNum = 0;
    }
  }

  void move(int moveToX, int moveToY) {
    status = MOVE;
    moveSpeed = MOVESPEED;
    target.setX(moveToX);
    target.setY(moveToY);
  }

  void run(int runToX, int runToY) {
    status = RUN;
    moveSpeed = RUNSPEED;
    target.setX(runToX);
    target.setY(runToY);
  }

  void attack(PICAIURecruittedUnit toAttack) {
    status = SHOOT;
    this.toAttack = toAttack;
    target.setX(toAttack.getX());
    target.setY(toAttack.getY());
  }

  private void shootTarget(PICAIURecruittedUnit toAttack) {

    if (status == SHOOT) {
      int a = PICAIUDice.roll(100);
      if (a <= accuracy) {
        toAttack.health--;
        if (toAttack.health <= 0) {
          toAttack.status = DEAD;
          status = NORMAL;
        }
      }
      energy--;
    }
  }

  int getVision() {
    return vision;
  }
}
